home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Oberon / source / Misc / ConvertSwitches.mod
Text File  |  1995-07-02  |  13KB  |  508 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: ConvertSwitches.mod $
  4.   Description: A utility to convert the old-style compiler switches to
  5.                new-style pragmas and options.
  6.  
  7.    Created by: fjc (Frank Copeland)
  8.     $Revision: 1.2 $
  9.       $Author: fjc $
  10.         $Date: 1995/01/26 01:05:15 $
  11.  
  12.   Copyright © 1994-1995, Frank Copeland.
  13.   This file is part of Oberon-A.
  14.   See Oberon-A.doc for conditions of use and distribution.
  15.  
  16. *************************************************************************)
  17.  
  18. <* STANDARD- *>
  19.  
  20. MODULE ConvertSwitches;
  21.  
  22. IMPORT
  23.   SYS := SYSTEM, Kernel, Errors, rev := ConvertSwitchesRev, e := Exec,
  24.   d := Dos, f := Files, Out, wb := Workbench, i := Icon, str := Strings;
  25.  
  26. CONST
  27.  
  28.   template = "FILES/A,TO/K,VERBOSE/S";
  29.   optFiles = 0;
  30.   optTo = 1;
  31.   optVerbose = 2;
  32.   optCount = 3;
  33.  
  34. VAR
  35.  
  36.   rdArgs : d.RDArgsPtr;
  37.   files  : e.LSTRPTR;
  38.   toDir  : e.LSTRPTR;
  39.  
  40. CONST
  41.   CopyrightStr = "Copyright © 1994-1995, Frank Copeland\n";
  42.   UsageStr     = "see Oberon-A.doc for conditions of use\n\n";
  43.  
  44. CONST
  45.  
  46.   PathLen = 255;
  47.  
  48. TYPE
  49.  
  50.   Path = ARRAY PathLen + 1 OF CHAR;
  51.  
  52. VAR
  53.  
  54.   (*
  55.     These variables are global so that they may be found by the Cleanup()
  56.     procedure in the event of an abnormal exit
  57.   *)
  58.  
  59.   input,      (* The current input file. *)
  60.   output      (* The current output file. *)
  61.     : f.File;
  62.  
  63.   r, w : f.Rider;
  64.   ch : CHAR;
  65.  
  66. CONST
  67.  
  68.   CR = 0DX; LF = 0AX; TAB = 09X; SP = " ";
  69.  
  70. VAR
  71.  
  72.   state, line, spaces : INTEGER;
  73.   quoteChar : CHAR;
  74.  
  75. CONST
  76.  
  77.   STARTLINE = 0;
  78.   WHITESPACE = 1;
  79.   COPYCHAR = 2;
  80.   LEFTBRACKET = 3;
  81.   STARTCOMMENT = 4;
  82.   COPYCOMMENT = 5;
  83.   DOLLAR = 6;
  84.   STAR = 7;
  85.   ENDCOMMENT = 8;
  86.   INSTRING = 9;
  87.   SWITCHCHAR = 10;
  88.  
  89.  
  90. (*------------------------------------*)
  91. PROCEDURE* Cleanup (VAR rc : LONGINT);
  92.  
  93. BEGIN (* Cleanup *)
  94.   IF input # NIL THEN f.Close (input) END;
  95.   IF output # NIL THEN f.Purge (output) END;
  96.   IF rdArgs # NIL THEN d.FreeArgs (rdArgs) END
  97. END Cleanup;
  98.  
  99. (*------------------------------------*)
  100. PROCEDURE Init ();
  101.  
  102. BEGIN (* Init *)
  103.   IF d.base.lib.version >= 37 THEN
  104.     Kernel.SetCleanup (Cleanup)
  105.   ELSE
  106.     Out.String (" !! ConvertSwitches requires OS release 2.04 or greater\n");
  107.     HALT (d.warn)
  108.   END
  109. END Init;
  110.  
  111. (*------------------------------------*)
  112. PROCEDURE CloneStr ( oldStr : e.LSTRPTR ) : e.LSTRPTR;
  113.   VAR newStr : e.LSTRPTR;
  114. BEGIN (* CloneStr *)
  115.   SYS.NEW (newStr, str.Length (oldStr^) + 1);
  116.   COPY (oldStr^, newStr^);
  117.   RETURN newStr
  118. END CloneStr;
  119.  
  120. (*------------------------------------*)
  121. PROCEDURE GetArgs ();
  122.  
  123.   VAR
  124.     argArray  : ARRAY optCount OF SYS.LONGWORD;
  125.     wbArg     : wb.WBArg;
  126.     wbStartup : wb.WBStartupPtr;
  127.     oldDir    : d.FileLockPtr;
  128.     diskObj   : wb.DiskObjectPtr;
  129.     string    : e.LSTRPTR;
  130.  
  131. BEGIN (* GetArgs *)
  132.   IF Kernel.fromWorkbench THEN
  133.     ASSERT (i.base # NIL, 100);
  134.  
  135.     wbStartup := SYS.VAL (wb.WBStartupPtr, Kernel.WBenchMsg);
  136.     Errors.Assert ( wbStartup.numArgs <= 2,
  137.                     "ConvertSwitches -- too many arguments" );
  138.  
  139.     oldDir := d.CurrentDir (wbStartup.argList[0].lock);
  140.     diskObj := i.GetDiskObject (wbStartup.argList[0].name^);
  141.     ASSERT (diskObj # NIL);
  142.     IF diskObj # NIL THEN
  143.       IF wbStartup.numArgs = 2 THEN
  144.         oldDir := d.CurrentDir (wbStartup.argList[1].lock);
  145.         string := wbStartup.argList[1].name
  146.       ELSE
  147.         string := NIL
  148.       END;
  149.       IF (string = NIL) OR (string^ = "") THEN
  150.         string := i.FindToolType (diskObj.toolTypes, "FILES")
  151.       END;
  152.       Errors.Assert (string # NIL, "ConvertSwitches -- no file specified");
  153.       files := CloneStr (string);
  154.       string := i.FindToolType (diskObj.toolTypes, "TO");
  155.       IF string # NIL THEN toDir := CloneStr (string) END;
  156.       i.FreeDiskObject (diskObj)
  157.     END;
  158.   ELSE
  159.     rdArgs := d.OldReadArgs (template, argArray, NIL);
  160.     IF rdArgs # NIL THEN
  161.       (*
  162.       ** files is guaranteed to contain something, because of the /A
  163.       ** toDir can be NIL
  164.       *)
  165.       files := SYS.VAL (e.LSTRPTR, argArray [optFiles]);
  166.       toDir := SYS.VAL (e.LSTRPTR, argArray [optTo]);
  167.     ELSE
  168.       ASSERT (d.PrintFault (d.IoErr(), "ReadArgs"));
  169.       HALT (d.error)
  170.     END
  171.   END;
  172. END GetArgs;
  173.  
  174. (*------------------------------------*)
  175. PROCEDURE MakeOutputName
  176.   (inputName : ARRAY OF CHAR; VAR outputName : ARRAY OF CHAR);
  177.  
  178.   VAR filePart : e.LSTRPTR;
  179.  
  180. <*$CopyArrays-*>
  181. BEGIN (* MakeOutputName *)
  182.   filePart := d.FilePart (inputName);
  183.   IF toDir = NIL THEN COPY ("", outputName)
  184.   ELSE COPY (toDir^, outputName)
  185.   END;
  186.   Errors.Assert
  187.     ( d.AddPart (outputName, filePart^, PathLen),
  188.       "Output file name too big" )
  189. END MakeOutputName;
  190.  
  191. (*------------------------------------*)
  192. PROCEDURE WriteSpaces ();
  193.  
  194. BEGIN (* WriteSpaces *)
  195.   WHILE spaces > 0 DO f.Write (w, SP); DEC (spaces) END
  196. END WriteSpaces;
  197.  
  198. (*------------------------------------*)
  199. PROCEDURE WriteString (s : ARRAY OF CHAR);
  200.  
  201.   VAR i : INTEGER; ch : CHAR;
  202.  
  203. <*$CopyArrays-*>
  204. BEGIN (* WriteString *)
  205.   i := 0; ch := s [0];
  206.   WHILE ch # 0X DO f.Write (w, ch); INC (i); ch := s [i] END
  207. END WriteString;
  208.  
  209. (*------------------------------------*)
  210. PROCEDURE CopyComment ();
  211.  
  212.   VAR switchChar : CHAR;
  213.  
  214. BEGIN (* CopyComment *)
  215.   state := COPYCOMMENT;
  216.   LOOP
  217.     CASE ch OF
  218.       LF :
  219.         IF state = DOLLAR THEN f.Write (w, "$") END;
  220.         IF state = SWITCHCHAR THEN
  221.           f.Write (w, "$"); f.Write (w, switchChar)
  222.         END;
  223.         f.Write (w, LF); INC (line);
  224.         IF (line MOD 10) = 0 THEN Out.Int (line, 0); Out.Char (CR) END;
  225.         state := COPYCOMMENT
  226.       |
  227.       "(" :
  228.         f.Write (w, ch); state := LEFTBRACKET
  229.       |
  230.       "*" :
  231.         f.Write (w, ch);
  232.         IF state = LEFTBRACKET THEN
  233.           f.Read (r, ch); CopyComment (); state := COPYCOMMENT
  234.         ELSE
  235.           state := STAR
  236.         END
  237.       |
  238.       ")" :
  239.         f.Write (w, ch);
  240.         IF state = STAR THEN EXIT ELSE state := COPYCOMMENT END
  241.       |
  242.       "$": IF state = DOLLAR THEN f.Write (w, "$") END; state := DOLLAR
  243.       |
  244.       "+", "-", "=":
  245.         IF state = SWITCHCHAR THEN
  246.           WriteString ("<*");
  247.           CASE switchChar OF
  248.             "C" : WriteString ("$CaseChk")
  249.             |
  250.             "I" : WriteString ("$IndexChk")
  251.             |
  252.             "L" : WriteString ("$LongVars")
  253.             |
  254.             "N" : WriteString ("$NilChk")
  255.             |
  256.             "R" : WriteString ("$RangeChk")
  257.             |
  258.             "S" : WriteString ("$StackChk")
  259.             |
  260.             "T" : WriteString ("$TypeChk")
  261.             |
  262.             "V" : WriteString ("$OvflChk")
  263.             |
  264.             "Z" : WriteString ("$ClearVars")
  265.             |
  266.             "A" : WriteString ("$SaveAllRegs")
  267.             |
  268.             "D" : WriteString ("$CopyArrays")
  269.             |
  270.             "r" : WriteString ("$ReturnChk")
  271.             |
  272.             "s" : WriteString ("$SaveRegs");
  273.             |
  274.             "P" : WriteString ("STANDARD");
  275.             |
  276.           END;
  277.           IF ch = "-" THEN f.Write (w, "-")
  278.           ELSE f.Write (w, "+")
  279.           END;
  280.           WriteString ("*>")
  281.         ELSE
  282.           f.Write (w, ch)
  283.         END;
  284.         state := COPYCOMMENT
  285.       |
  286.     ELSE
  287.       IF state = DOLLAR THEN
  288.         CASE ch OF
  289.           "P", "C", "I", "L", "N", "R", "S",
  290.           "T", "V", "Z", "A", "D", "r", "s" :
  291.             switchChar := ch; state := SWITCHCHAR
  292.           |
  293.         ELSE
  294.           f.Write (w, "$"); f.Write (w, ch); state := COPYCOMMENT
  295.         END;
  296.       ELSIF state = SWITCHCHAR THEN
  297.         f.Write (w, "$"); f.Write (w, switchChar); f.Write (w, ch);
  298.         state := COPYCOMMENT
  299.       ELSE
  300.         f.Write (w, ch); state := COPYCOMMENT
  301.       END;
  302.     END;
  303.     f.Read (r, ch);
  304.     IF r.eof THEN
  305.       Out.String (" !! End of file encountered in CopyComment()\n"); EXIT
  306.     END
  307.   END
  308. END CopyComment;
  309.  
  310. (*------------------------------------*)
  311. PROCEDURE ChangeState ();
  312.  
  313. BEGIN (* ChangeState *)
  314.   CASE state OF
  315.     STARTLINE :
  316.       INC (line);
  317.       IF (line MOD 10) = 0 THEN Out.Int (line, 0); Out.Char (CR) END;
  318.       spaces := 0;
  319.       CASE ch OF
  320.         LF : f.Write (w, ch); state := STARTLINE
  321.         |
  322.         SP : INC (spaces); state := WHITESPACE
  323.         |
  324.         TAB : INC (spaces, 8); state := WHITESPACE
  325.         |
  326.         "(" : state := LEFTBRACKET
  327.         |
  328.         "'", '"' :
  329.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  330.         |
  331.       ELSE
  332.         f.Write (w, ch); state := COPYCHAR
  333.       END;
  334.     |
  335.     WHITESPACE :
  336.       CASE ch OF
  337.         LF : f.Write (w, ch); state := STARTLINE
  338.         |
  339.         SP : INC (spaces); state := WHITESPACE
  340.         |
  341.         TAB : INC (spaces, 8); state := WHITESPACE
  342.         |
  343.         "(" : state := LEFTBRACKET
  344.         |
  345.         "'", '"' :
  346.           WriteSpaces(); f.Write (w, ch); state := INSTRING;
  347.           quoteChar := ch
  348.         |
  349.       ELSE
  350.         WriteSpaces(); f.Write (w, ch); state := COPYCHAR
  351.       END;
  352.     |
  353.     COPYCHAR :
  354.       CASE ch OF
  355.         LF : f.Write (w, ch); state := STARTLINE
  356.         |
  357.         SP : INC (spaces); state := WHITESPACE
  358.         |
  359.         TAB : INC (spaces, 8); state := WHITESPACE
  360.         |
  361.         "(" : state := LEFTBRACKET
  362.         |
  363.         "'", '"' :
  364.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  365.         |
  366.       ELSE
  367.         f.Write (w, ch); state := COPYCHAR
  368.       END;
  369.     |
  370.     LEFTBRACKET :
  371.       CASE ch OF
  372.         "*" : state := STARTCOMMENT
  373.         |
  374.         LF :
  375.           WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
  376.           state := STARTLINE
  377.         |
  378.         SP :
  379.           WriteSpaces (); f.Write (w, "("); spaces := 1;
  380.           state := WHITESPACE
  381.         |
  382.         TAB :
  383.           WriteSpaces (); f.Write (w, "("); spaces := 8;
  384.           state := WHITESPACE
  385.         |
  386.         "(" :
  387.           WriteSpaces (); f.Write (w, "("); state := LEFTBRACKET
  388.         |
  389.         "'", '"' :
  390.           WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
  391.           state := INSTRING; quoteChar := ch
  392.         |
  393.       ELSE
  394.         WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
  395.         state := COPYCHAR
  396.       END;
  397.     |
  398.     STARTCOMMENT :
  399.       WriteSpaces(); WriteString ("(*"); CopyComment(); state := ENDCOMMENT
  400.     |
  401.     ENDCOMMENT :
  402.       CASE ch OF
  403.         LF : f.Write (w, ch); state := STARTLINE
  404.         |
  405.         SP : INC (spaces); state := WHITESPACE
  406.         |
  407.         TAB : INC (spaces, 8); state := WHITESPACE
  408.         |
  409.         "(" : state := LEFTBRACKET
  410.         |
  411.         "'", '"' :
  412.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  413.         |
  414.       ELSE
  415.         f.Write (w, ch); state := COPYCHAR
  416.       END;
  417.     |
  418.     INSTRING :
  419.       f.Write (w, ch); IF ch = quoteChar THEN state := COPYCHAR END
  420.     |
  421.   END
  422. END ChangeState;
  423.  
  424. (*------------------------------------*)
  425. PROCEDURE Strip (inputName : ARRAY OF CHAR);
  426.  
  427.   VAR outputName : Path;
  428.  
  429. <*$CopyArrays-*>
  430. BEGIN (* Strip *)
  431.   input := f.Old (inputName);
  432.   IF input # NIL THEN
  433.     MakeOutputName (inputName, outputName);
  434.     output := f.New (outputName);
  435.     IF output # NIL THEN
  436.       Out.String (" !! "); Out.String (inputName);
  437.       Out.String (" -> "); Out.String (outputName);
  438.       Out.Ln;
  439.       f.Set (r, input, 0);
  440.       f.Set (w, output, 0);
  441.       spaces := 0; state := WHITESPACE; line := 1;
  442.       WHILE ~r.eof DO
  443.         f.Read (r, ch);
  444.         ChangeState ()
  445.       END;
  446.       f.Close (input);
  447.       f.Register (output)
  448.     ELSE
  449.       f.Close (input);
  450.       Out.String (" !! Could not open "); Out.String (outputName);
  451.       Out.String (" for output"); Out.Ln;
  452.     END
  453.   ELSE
  454.     Out.String (" !! Could not open "); Out.String (inputName);
  455.     Out.String (" for input"); Out.Ln;
  456.   END;
  457.  
  458.   input := NIL; output := NIL;
  459.   f.Set (r, NIL, 0); f.Set (w, NIL, 0);
  460.   Kernel.GC
  461. END Strip;
  462.  
  463. (*------------------------------------*)
  464. PROCEDURE Main ();
  465.  
  466.   VAR
  467.     i : INTEGER; modName : ARRAY 32 OF CHAR;
  468.     myAnchor : d.AnchorPathPtr; result : LONGINT;
  469.     fileName : ARRAY 256 OF CHAR;
  470.  
  471. BEGIN (* Main *)
  472.   (* myAnchor is allocated because it must be longword aligned *)
  473.   NEW (myAnchor);
  474.   myAnchor.strlen := SHORT (LEN (myAnchor.buf));
  475.   (* Find the first file matching the pattern *)
  476.   result := d.MatchFirst (files^, myAnchor^);
  477.   WHILE result = 0 DO
  478.     (* Strip the file and get the next name. *)
  479.     Strip (myAnchor.buf);
  480.     (* Get the next matching file *)
  481.     result := d.MatchNext (myAnchor^)
  482.   END;
  483.   d.MatchEnd (myAnchor^); (* Clean up anchor data *)
  484. END Main;
  485.  
  486. (*------------------------------------*)
  487. BEGIN (* ConvertSwitches *)
  488.   Errors.Init;
  489.  
  490.   Out.String (rev.vString);
  491.   Out.String (CopyrightStr);
  492.   Out.String (UsageStr);
  493.  
  494.   Init ();
  495.   GetArgs ();
  496.   Main ();
  497.  
  498.   Out.String ("\x9B\x4B !! All done\n")
  499. END ConvertSwitches.
  500.  
  501. (*************************************************************************
  502.  
  503.   $Log: ConvertSwitches.mod $
  504. # Revision 1.2  1995/01/26  01:05:15  fjc
  505. # - Release 1.5
  506. #
  507. *************************************************************************)
  508.